from pathlib import Path

from PySide6.QtCore import Qt, QSize, QPoint, Signal
from PySide6.QtGui import QImage, QPixmap, QResizeEvent
from PySide6.QtWidgets import *
from components import DragButton, ImgCard, OpenFileDialog
from qfluentwidgets import ListWidget, PushButton, FluentIcon, ComboBox, ImageLabel, TitleLabel, InfoBar, StateToolTip, \
    LineEdit, LineEditButton
from view.base import ReturnView
from resource import WordPng
from common import ImageConversionThread


class OneTypeView(ReturnView):
    synced = Signal(str, str, str)

    def __init__(self, parent=None):
        super().__init__(parent)
        self.__initWidget()
        self.__initLayout()
        self.__initEvent()

    def __initWidget(self):
        self.hBox1 = QHBoxLayout()
        self.hBox1.setContentsMargins(100, 100, 100, 50)
        self.hBox1.setSpacing(30)
        self.hBox1.setAlignment(Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignVCenter)
        self.titleLabel = TitleLabel('图片格式转换')
        self.comboBox = ComboBox()
        self.comboBox.setFixedSize(200, 40)
        self.comboBox.addItems(['WebP', 'JPG', 'PNG', 'BMP', 'ICO'])

        self.imageLabel = ImageLabel(self)
        self.imageLabel.setImage(QPixmap(WordPng.TRANS.path()).scaled(
            40, 40, Qt.AspectRatioMode.KeepAspectRatioByExpanding, Qt.TransformationMode.SmoothTransformation
        ))

        self.toComboBox = ComboBox()
        self.toComboBox.addItems(['WebP', 'JPG', 'PNG', 'BMP', 'ICO'])
        self.toComboBox.setFixedSize(200, 40)

        self.sizeComboBox = ComboBox()
        self.sizeComboBox.setFixedSize(200, 40)
        self.sizeComboBox.addItems(
            ['16x16', '24x24', '32x32', '48x48', '64x64', '72x72', '80x80', '96x96', '128x128', '256x256']
        )
        self.sizeComboBox.hide()

        self.syncButton = PushButton(FluentIcon.SYNC, '去转换', self)
        self.syncButton.setFixedSize(500, 40)

    def __initEvent(self):
        self.toComboBox.currentTextChanged.connect(self.on_comboBox_currentTextChanged)
        self.syncButton.clicked.connect(self.on_syncButton_clicked)

    def __initLayout(self):
        self.vBox.addWidget(self.titleLabel, 0, Qt.AlignCenter)
        self.hBox1.addWidget(self.comboBox, 0, Qt.AlignmentFlag.AlignCenter)
        self.hBox1.addWidget(self.imageLabel, 0, Qt.AlignmentFlag.AlignCenter)
        self.hBox1.addWidget(self.toComboBox, 0, Qt.AlignmentFlag.AlignCenter)
        self.hBox1.addWidget(self.sizeComboBox, 0, Qt.AlignmentFlag.AlignCenter)
        self.vBox.addLayout(self.hBox1)
        self.vBox.addWidget(self.syncButton, 0, Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignVCenter)

    def on_syncButton_clicked(self):
        from_t, to_t = self.currentText()
        size = self.sizeComboBox.currentText()
        self.synced.emit(from_t, to_t, size)

    def currentText(self):
        from_t = self.comboBox.currentText()
        to_t = self.toComboBox.currentText()
        return from_t, to_t

    def on_comboBox_currentTextChanged(self, text):
        if text == 'ICO':
            self.sizeComboBox.show()
        else:
            self.sizeComboBox.hide()


class TwoConversionView(ReturnView):
    """
    图片格式转换
    """
    started = Signal(str, str)

    def __init__(self, parent=None):
        super().__init__(parent)
        self.widgets = []
        self.from_t = None  # type: str
        self.to_t = None  # type: str
        self.stateToolTip = None  # type: StateToolTip
        self.img_size = None  # type: str

        self.titleLabel = TitleLabel(self)
        self.dragButton = DragButton(self)
        self.deleteButton = PushButton(FluentIcon.DELETE, '全部删除', self)
        self.listWidget = ListWidget(self)
        self.saveLineEdit = LineEdit(self)
        self.saveLineEdit.setReadOnly(True)
        self.saveLineEdit.setPlaceholderText('请选择保存路径...')
        self.saveButton = LineEditButton(FluentIcon.FOLDER)
        self.saveLineEdit.hBoxLayout.addWidget(self.saveButton)
        self.startButton = PushButton(FluentIcon.SYNC, '开始转换', self)
        self.conversionThread = ImageConversionThread(self)

        self.__initEvent()
        self.__initLayout()

    def __initEvent(self):
        self.deleteButton.clicked.connect(self.clear)
        self.dragButton.clicked.connect(self.on_dragButton_connect)
        self.dragButton.dropUrl.connect(self.addItem)
        self.startButton.clicked.connect(self.on_startButton_clicked)
        self.saveButton.clicked.connect(self.on_saveButton_clicked)

        self.conversionThread.started.connect(self.on_conversionThread_started)
        self.conversionThread.finished.connect(self.on_conversionThread_finished)
        self.conversionThread.error.connect(self.on_conversionThread_error)
        self.conversionThread.progress.connect(lambda content: self.stateToolTip.setContent(content))

    def __initLayout(self):
        self.vBox.addWidget(self.titleLabel, 0, Qt.AlignmentFlag.AlignHCenter)
        self.vBox.addWidget(self.dragButton)
        self.vBox.addWidget(self.deleteButton, 0, Qt.AlignmentFlag.AlignRight)
        self.vBox.addWidget(self.listWidget)
        self.vBox.addWidget(self.saveLineEdit)
        self.vBox.addWidget(self.startButton)

    def addItem(self, filename):
        # 判断是否是相应的文件
        if Path(filename).suffix != f'.{self.from_t.lower()}':
            return

        img_card = ImgCard(filename, self)
        img_card.closed.connect(self.on_closed_connect)
        item = QListWidgetItem()
        item.setSizeHint(img_card.sizeHint())
        item.setFlags(item.flags() | Qt.ItemIsSelectable)
        self.listWidget.addItem(item)
        self.listWidget.setItemWidget(item, img_card)
        self.widgets.append(img_card)
        return img_card

    def on_closed_connect(self, button: QPushButton):
        button_pos = button.mapToGlobal(QPoint(0, 0)) - self.listWidget.mapToGlobal(QPoint(0, 0))
        item = self.listWidget.indexAt(button_pos)
        row = item.row()
        listItem = self.listWidget.item(row)
        self.listWidget.removeItemWidget(listItem)
        self.listWidget.takeItem(row)
        self.widgets.pop(row)

    def on_dragButton_connect(self):
        files = OpenFileDialog(self).getOpenFileNames(filter=f'图片文件(*.{self.from_t.lower()})')[0]
        for file in files:
            if file in self.texts():
                continue
            self.addItem(file)

    def texts(self):
        t = []
        for widget in self.widgets:
            t.append(widget.text())
        return t

    def clear(self):
        self.listWidget.clear()
        del self.widgets
        self.widgets = []

    def setText(self, from_t: str, to_t: str, size: str):
        self.from_t = from_t
        self.to_t = to_t
        self.img_size = size

    def setTitle(self, text: str):
        self.titleLabel.setText(text)

    def on_conversionThread_started(self):
        if self.stateToolTip is None:
            self.stateToolTip = StateToolTip('图片转换', '正在进行图片转换，请稍后...', self)
        self.stateToolTip.show()

    def on_conversionThread_finished(self):
        InfoBar.success('提示', '图片转换完成', duration=3000, parent=self)
        self.stateToolTip.close()

    def on_conversionThread_error(self, msg):
        InfoBar.error('错误', msg, duration=5000, parent=self)

    def on_startButton_clicked(self):
        files = self.texts()
        save_file = self.saveLineEdit.text()
        if len(files) == 0 or save_file == '':
            InfoBar.warning('提示', '请选择相应数据', duration=3000, parent=self)
            return
        self.conversionThread.set_value(self.from_t, self.to_t, files, save_file, self.img_size)
        self.conversionThread.start()

    def on_saveButton_clicked(self):
        file = OpenFileDialog(self).getExistingDirectory()
        self.saveLineEdit.setText(file)

    def resizeEvent(self, event: QResizeEvent):
        super().resizeEvent(event)
        if self.stateToolTip:
            self.stateToolTip.move(event.size().width() - self.stateToolTip.width(), 10)


class PictureConversionView(QFrame):
    returned = Signal()

    def __init__(self, parent=None):
        super().__init__(parent)

        self.stackedWidget = QStackedWidget(self)

        self.oneView = OneTypeView()
        self.twoView = TwoConversionView()

        self.__initLayout()
        self.__initEvent()

    def __initLayout(self):
        self.vBox = QVBoxLayout(self)
        self.vBox.setContentsMargins(0, 0, 0, 0)
        self.vBox.setSpacing(0)
        self.vBox.addWidget(self.stackedWidget)

        self.stackedWidget.addWidget(self.oneView)
        self.stackedWidget.addWidget(self.twoView)

    def __initEvent(self):
        self.oneView.synced.connect(self.on_oneView_clicked)
        self.oneView.returned.connect(self.returned.emit)
        self.twoView.returned.connect(lambda: self.switchTo(self.oneView))
        # self.twoView.started.connect(lambda: self.switchTo(self.twoView))

    def on_oneView_clicked(self, from_t, to_t, size):
        self.twoView.setTitle(f'{from_t} 转 {to_t} 转换器')
        self.twoView.setText(from_t, to_t, size)
        self.switchTo(self.twoView)

    def switchTo(self, widget):
        self.stackedWidget.setCurrentWidget(widget)


if __name__ == '__main__':
    import sys

    app = QApplication(sys.argv)
    win = PictureConversionView()
    win.resize(800, 500)
    win.show()
    sys.exit(app.exec())
